// Calendar.vue
<template>
  <view class="calendar-container">
    <!-- 月份切换 -->
    <view class="header">
      <text class="arrow" @click="changeMonth(-1)">←</text>
      <text class="month-title">{{ currentYear }}年{{ currentMonth + 1 }}月</text>
      <text class="arrow" @click="changeMonth(1)">→</text>
    </view>

    <!-- 星期标题 -->
    <view class="weekdays">
      <text v-for="day in weekDays" :key="day">{{ day }}</text>
    </view>

    <!-- 日期网格 -->
    <view class="days-grid">
      <view 
        v-for="(day, index) in days" 
        :key="index"
        class="day-item"
        :class="{
          'not-current-month': !day.isCurrentMonth,
          'has-events': day.events && day.events.length > 0
        }"
        @click="handleDayClick(day)"
      >
        <text class="day-number" :class="{ 'today': day.isToday }">{{ day.date }}</text>
        <view class="events-container" v-if="Array.isArray(day.events) && day.events.length > 0">
          <view 
            v-for="(event, eIndex) in day.events.slice(0, 3)" 
            :key="eIndex"
            class="event-item"
            :class="{
              'event-start': event.position === 'start',
              'event-middle': event.position === 'middle',
              'event-end': event.position === 'end',
              'event-single': !event.isMultiDay
            }"
            :style="{ 
              backgroundColor: event.color ? `${event.color}20` : `${getEventColor(eIndex)}20`, 
              borderLeftColor: event.position !== 'middle' && event.position !== 'end' ? event.color || getEventColor(eIndex) : 'transparent',
              borderRightColor: event.position !== 'middle' && event.position !== 'start' ? event.color || getEventColor(eIndex) : 'transparent'
            }"
          >
            <text class="event-title" v-if="!event.isMultiDay">{{ truncateTitle(event.title) }}</text>
            <text class="event-title" v-if="event.position === 'start' && event.isMultiDay ">{{ event.title }}</text>
          </view>
          <text v-if="day.events.length > 3" class="more-events">+{{ day.events.length - 3 }} 更多</text>
        </view>
      </view>
    </view>

    <!-- 弹窗 -->
    <uni-popup ref="popupRef" type="bottom" backgroud-color="#fff">
      <NewOptionsPopup 
        :date="selectedDate"
        :events="getSelectedDayEvents()"
        @delete-event="handleEventDelete"
      ></NewOptionsPopup>
    </uni-popup>
  </view>
</template>

<script lang="ts" setup>
import { ref, computed, type Ref, watch } from 'vue'
import NewOptionsPopup from './NewOptionsPopup.vue'
import type {CalendarEvent, Day, DailyEvent} from '@/types/calendar'
import { getEventInfoAPI } from '@/services/calendar';

interface Props {
  events?: string[]
}

const props = withDefaults(defineProps<Props>(), {
  events: () => []
})

// 表单数据
const formData = ref<CalendarEvent>({
    id: '',
    beginDate: '',
    endDate: '',
    title: '',
    description: ''
})

const eventList =ref<CalendarEvent[]>([])

const weekDays = ['日', '一', '二', '三', '四', '五', '六']
const currentDate = ref(new Date())
const selectedDate = ref('')
const popupRef = ref<{
  open: (type?: UniHelper.UniPopupType) => void
  close: () => void
}>()

// 计算属性
const currentYear = computed(() => currentDate.value.getFullYear())
const currentMonth = computed(() => currentDate.value.getMonth())

const formatDate = (year: number, month: number, date: number): string => {
  return `${year}-${(month + 1).toString().padStart(2, '0')}-${date.toString().padStart(2, '0')}`
}

const isToday = (fullDate: string): boolean => {
  return fullDate === formatDate(
    new Date().getFullYear(),
    new Date().getMonth(),
    new Date().getDate()
  )
}
const days = ref<Day[]>([])

// 初始化日历数据
const initCalendar = async () => {
  try {
    const daysArray: Day[] = []
    const date = new Date(currentDate.value)
    date.setDate(1) // 当月第一天
    
    
    // 上月日期处理
    // prevMonthDays 当月第一天是周几 比如2月 prevMonthDays为6
    const prevMonthDays = date.getDay()
    date.setMonth(date.getMonth())
    // date 设置为上月最后一天, lastDayPrevMonth为该月有多少天，比如这里是一月：31天
    date.setDate(0)
    const lastDayPrevMonth = date.getDate()
    
    const calendarFirstDay = formatDate(
        date.getFullYear(),
        date.getMonth(),
        lastDayPrevMonth - prevMonthDays + 1
      )

    // 添加上月日期，每一次循环里，fullDate会从 周日->周一 生成上月日期，直到本月第一天
    for (let i = prevMonthDays; i > 0; i--) {
      const fullDate = formatDate(
        date.getFullYear(),
        date.getMonth(),
        lastDayPrevMonth - i + 1
      )
      daysArray.push({
        date: lastDayPrevMonth - i + 1,
        isCurrentMonth: false,
        fullDate,
      })
    }

    // 当月日期处理
    date.setMonth(currentMonth.value + 1)
    date.setDate(0)
    const currentMonthDays = date.getDate()

    for (let i = 1; i <= currentMonthDays; i++) {
      const fullDate = formatDate(currentYear.value, currentMonth.value, i)
      daysArray.push({
        date: i,
        isCurrentMonth: true,
        isToday: isToday(fullDate),
        hasEvent: props.events.includes(fullDate),
        fullDate,
      })
    }

    const calendarLastDay = formatDate(
      date.getFullYear(),
      date.getMonth() + 1,
      42 - prevMonthDays - date.getDate()
    )

    // 补充下月日期
    let nextMonthDay = 1
    while (daysArray.length < 42) {
      const fullDate = formatDate(
        date.getFullYear(),
        date.getMonth() + 1,
        nextMonthDay
      )
      daysArray.push({
        date: nextMonthDay,
        isCurrentMonth: false,
        fullDate,
      })
      nextMonthDay++
    }
   
    formData.value.beginDate = calendarFirstDay
    formData.value.endDate = calendarLastDay
    
    // 获取事件数据
    const res = await getEventInfoAPI(formData.value)
    eventList.value = res.result
    
    // 将事件映射到日期
    const mapEventsToDay = () => {
      if (!eventList.value || eventList.value.length === 0) return
      
      // 遍历所有事件
      eventList.value.forEach(event => {
        const startDate = new Date(event.beginDate)
        const endDate = new Date(event.endDate)
        
        // 判断是否为跨天事件
        const isMultiDay = endDate.getTime() - startDate.getTime() > 24 * 60 * 60 * 1000
        
        // 处理跨天事件
        for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
          const dateStr = formatDate(
            d.getFullYear(),
            d.getMonth(),
            d.getDate()
          )
          
          // 确定当前日期在事件中的位置
          const isFirstDay = d.getTime() === startDate.getTime()
          const isLastDay = d.getTime() === endDate.getTime()
          const position = isFirstDay ? 'start' : isLastDay ? 'end' : 'middle'
          
          // 找到对应的日期并添加事件
          const dayIndex = daysArray.findIndex(day => day.fullDate === dateStr)
          if (dayIndex !== -1) {
            if (!daysArray[dayIndex].events) {
              daysArray[dayIndex].events = []
            }
            // 添加事件位置信息
            daysArray[dayIndex].events.push({
              ...event,
              position,
              isMultiDay
            })
          }
        }
      })
    }
    
    // 调用函数映射事件
    mapEventsToDay()
    
    days.value = daysArray
  } catch (error) {
    console.error('日历初始化失败:', error)
    uni.showToast({
      title: '数据加载失败',
      icon: 'error'
    })
  }
}

// 监听月份变化时重新加载日历
watch([currentYear, currentMonth], () => {
  initCalendar()
}, { immediate: true })

// 方法
const changeMonth = (step: number) => {
  const newDate = new Date(currentDate.value)
  newDate.setMonth(currentMonth.value + step)
  currentDate.value = newDate
}

// 获取选中日期的事件
const getSelectedDayEvents = () => {
  if (!selectedDate.value || !days.value.length) return []
  const selectedDay = days.value.find(day => day.fullDate === selectedDate.value)
  return selectedDay && selectedDay.events ? selectedDay.events : []
}

const handleDayClick = (day: Day) => {
  selectedDate.value = day.fullDate
  popupRef.value?.open()
  console.log('选中日期的事件:', day.events)
}

const closePopup = () => {
  popupRef.value?.close()
}

//给一个网格中的不同事件色块设置不同的颜色
const getEventColor = (index: number) => {
  const colors = ['#007AFF', '#FF9500', '#4CD964', '#FF2D55', '#5856D6']
  return colors[index % colors.length]
}

//裁切标题长度
const truncateTitle = (title: string) => {
  return title.length > 8 ? title.substring(0, 8) : title
}

// 处理事件删除
const handleEventDelete = async () => {
  // 重新初始化日历数据
  await initCalendar()
  // 关闭弹窗
  //popupRef.value?.close()
}

</script>

<style scoped>
/* 保持原有样式不变 */
.calendar-container {
  padding: 0;
  width: 100%;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20rpx 0;
  font-size: 34rpx;
}

.month-title {
  font-weight: bold;
}

.arrow {
  padding: 0 20rpx;
  font-size: 40rpx;
}

.weekdays {
  display: flex;
  justify-content: space-around;
  padding: 20rpx 0;
  background-color: #f5f5f5;
  border-radius: 10rpx;
  width: 100%;
}

.days-grid {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  margin-top: 10rpx;
}

.day-item {
  width: 14.28%;
  aspect-ratio: 9/16;
  display: flex;
  flex-direction: column;
  padding: 5rpx 0;
  border-radius: 10rpx;
  box-sizing: border-box;
}

.day-number {
  text-align: center;
  margin-bottom: 5rpx;
  padding: 5rpx;
  border-radius: 50%;
  width: 35rpx;
  height: 35rpx;
  line-height: 40rpx;
  display: inline-block;
  margin: 0 auto 5rpx;
  box-sizing: content-box;
}

.not-current-month {
  color: #ccc;
}

.today {
  background-color: #007AFF;
  color: white;
}

.events-container {
  display: flex;
  flex-direction: column;
  gap: 2rpx;
  font-size: 16rpx;
  overflow: hidden;
}

.event-item {
  padding: 2rpx 4rpx;
  border-radius: 16rpx;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  position: relative;
  min-height: 32rpx;
  margin: 0 2rpx;
  flex-shrink: 0;
  text-align: center;
}

.event-single {
  border-radius: 4rpx;
  margin: 0;
}

.event-start {
  border-top-left-radius: 8rpx;
  border-bottom-left-radius: 8rpx;
  border-top-right-radius: 8rpx;
  border-bottom-right-radius: 8rpx;
  margin-right: -1px;
  padding-right: 1px;
}

.event-middle {
  border-radius: 0rpx;
  margin-left: -1px;
  margin-right: -1px;
  padding-left: 1px;
  padding-right: 1px;
}

.event-end {
  border-top-right-radius: 8rpx;
  border-bottom-right-radius: 8rpx;
  border-top-left-radius: 0rpx;
  border-bottom-left-radius: 8rpx;
  margin-left: -1px;
  padding-left: 1px;
}

.event-title {
  font-size: 24rpx;
  color: #333;
  
}

.more-events {
  font-size: 24rpx;
  color: #999;
  text-align: center;
  margin-top: 2rpx;
  flex-shrink: 0;
  height: 20rpx;
}

</style>